package summer.codegenerator.web;

import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import summer.codegenerator.common.annotation.ExportEnum;
import summer.codegenerator.common.util.ClazzUtil;
import summer.codegenerator.common.util.PoiUtil;

/**
 * 公共请求
 * 请求枚举、国际化等数据
 * 
 * @author 蒋振
 * @since 2019年6月25日 下午4:11:25
 */
@Controller
@RequestMapping("/common")
@ResponseBody
public class CommonController {

	private final String modelEnumerationPath = "summer.codegenerator.model.enumeration";

	@RequestMapping("/list/enum")
	public Map<String, List<Map<String, Object>>> listEnum() throws ClassNotFoundException, IllegalAccessException,
			IllegalArgumentException, InvocationTargetException {
		List<Class<?>> clazzs = ClazzUtil.getClassListByAnnotation(modelEnumerationPath, ExportEnum.class);
		Map<String, List<Map<String, Object>>> ret = new HashMap<String, List<Map<String, Object>>>();
		for (Class<?> clazz : clazzs) {
			Method[] methods = clazz.getDeclaredMethods();
			if (clazz.isEnum()) {
				List<Map<String, Object>> enumDto = new ArrayList<Map<String, Object>>();
				List<?> enumConstants = Arrays.asList(clazz.getEnumConstants());
				for (Object enumConstant : enumConstants) {
					Map<String, Object> enumMap = new HashMap<String, Object>();
					for (Method method : methods) {
						String methodName = method.getName();
						if (methodName.startsWith("get")) {
							String valueName = methodName.substring(3);
							valueName = valueName.substring(0, 1).toLowerCase() + valueName.substring(1);
							enumMap.put(valueName, method.invoke(enumConstant));
						}
					}
					enumDto.add(enumMap);
				}
				ret.put(clazz.getSimpleName().toUpperCase(), enumDto);
			}
		}

		return ret;
	}

	@RequestMapping(value = "/export/enum")
	public void export(HttpServletRequest request, HttpServletResponse response) throws Exception {

		// excel标题
		String[] title = { "枚举编码", "值", "描述" };

		// excel文件名
		String fileName = URLEncoder.encode("枚举", "UTF-8") + ".xls";

		// sheet名
		String sheetName = "所有";
		List<String[]> enumlist = new ArrayList<>();
		List<Class<?>> clazzs = ClazzUtil.getClassListByAnnotation(modelEnumerationPath, ExportEnum.class);
		for (Class<?> clazz : clazzs) {
			if (clazz.isEnum()) {
				String clazzSimpleName = clazz.getSimpleName();
				List<?> enumConstants = Arrays.asList(clazz.getEnumConstants());
				for (Object enumConstant : enumConstants) {
					Object enumValue = clazz.getDeclaredMethod("getIndex").invoke(enumConstant);
					Object enumText = clazz.getDeclaredMethod("getText").invoke(enumConstant);
					enumlist.add(new String[]{clazzSimpleName, enumValue.toString(), enumText.toString()});
				}
			}
		}

		String[][] content = new String[enumlist.size()][];
		enumlist.toArray(content);

		// 创建HSSFWorkbook
		HSSFWorkbook wb = PoiUtil.getHSSFWorkbook(sheetName, title, content, null);

		// 响应到客户端
		try {
			this.setResponseHeader(response, fileName);
			OutputStream os = response.getOutputStream();
			wb.write(os);
			os.flush();
			os.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送响应流方法
	private void setResponseHeader(HttpServletResponse response, String fileName) {
		try {
			try {
				fileName = new String(fileName.getBytes(), "UTF-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			response.setContentType("application/octet-stream;charset=UTF-8");
			response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
			response.addHeader("Pargam", "no-cache");
			response.addHeader("Cache-Control", "no-cache");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}
